package handler

import (
	"net/http"
	"path"
	"strings"
	"time"
	"yunpan/db"
	"yunpan/store/ceph"
	"yunpan/utils"

	"github.com/gin-gonic/gin"
)

// 获取文件列表
func GetFileList(c *gin.Context) {
    username := c.MustGet("username").(string)
    if username == "" {
        c.JSON(http.StatusBadRequest, gin.H{
            "code": 400,
            "msg":  "用户未登录",
        })
        return
    }

    fileType := c.Query("type")    // 获取文件类型参数
    currentPath := c.Query("path")

    if currentPath == "" {
        currentPath = "/"
    }

    var files []db.UserFile
    var err error

    // 根据不同类型获取文件列表
    switch fileType {
    case "recent":
        files, err = db.GetRecentFiles(username, 7)  // 获取最近7天的文件
    case "video":
        files, err = db.GetFilesByType(username, []string{".mp4", ".avi", ".mov"})
    case "image":
        files, err = db.GetFilesByType(username, []string{".jpg", ".jpeg", ".png", ".gif"})
    case "doc":
        files, err = db.GetFilesByType(username, []string{".doc", ".docx", ".pdf", ".txt",".md",".go",".cpp",".h",".py"})
    default: // "all" 或其他情况
        files, err = db.GetUserFileList(username, currentPath)
    }

    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{
            "code": 500,
            "msg":  "获取文件列表失败: " + err.Error(),
        })
        return
    }

    // 转换为前端需要的格式
    var fileList []gin.H
    for _, file := range files {
		// 确保文件夹路径以 / 结尾
		path := file.ParentPath + file.FileName
		if file.IsFolder && !strings.HasSuffix(path, "/") {
			path = path + "/"
		}
        fileList = append(fileList, gin.H{
            "id":         file.FileHash,
            "name":       file.FileName,
            "size":       file.FileSize,
            "updateTime": file.LastUpdate.Format("2006-01-02 15:04:05"),
            "type":       getFileType(file.FileName, file.IsFolder),
            "isFolder":   file.IsFolder,
            "path":       file.ParentPath + file.FileName,
        })
    }

    c.JSON(http.StatusOK, gin.H{
        "code": 200,
        "data": gin.H{
            "files": fileList,
            "total": len(fileList),
        },
    })
}

func getFileType(fileName string, isFolder bool) string {
	// 如果是文件夹，直接返回
	if isFolder {
		return "folder"
	}

	// 否则按扩展名判断文件类型
	ext := strings.ToLower(path.Ext(fileName))
	switch ext {
	case ".jpg", ".jpeg", ".png", ".gif":
		return "image"
	case ".mp4", ".avi", ".mov":
		return "video"
	case ".doc", ".docx", ".pdf", ".txt",".md":
		return "document"
	default:
		return "other"
	}
}

// 创建文件夹
func CreateFolder(c *gin.Context) {
	// 从header中获取username
	username := c.MustGet("username").(string)
	if username == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 400,
			"msg":  "用户未登录",
		})
		return
	}

	// 获取请求参数
	var req struct {
		Name string `json:"name" binding:"required"`
		Path string `json:"path"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 400,
			"msg":  "参数错误",
		})
		return
	}

	// 处理路径
	parentPath := req.Path
	if parentPath == "" {
		parentPath = "/"
	}

	// 生成文件夹的唯一标识
	folderHash := utils.Sha1([]byte(username + req.Name + parentPath + time.Now().String()))

	// 在 Ceph 中创建一个空对象作为文件夹标记
	// 使用 .folder 后缀来标识这是一个文件夹
	folderKey := parentPath + req.Name + "/.folder"

	// 在数据库中创建文件夹记录
	err := db.CreateUserFolder(username, req.Name, parentPath, folderHash)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  "创建文件夹失败: " + err.Error(),
		})
		return
	}
	cephConn, err := ceph.GetCephConn(username)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  "获取存储连接失败",
		})
		return
	}

	if err := cephConn.UploadObject(folderKey, []byte{}); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  "创建文件夹失败: " + err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "创建成功",
	})
}

func RenameFile(c *gin.Context) {
	username := c.MustGet("username").(string)
	var req struct {
		FileID  string `json:"fileId"`
		NewName string `json:"newName"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 400,
			"msg":  "参数错误",
		})
		return
	}

	err := db.RenameUserFile(username, req.FileID, req.NewName)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 400,
			"msg":  err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "重命名成功",
	})
}

// 删除文件
func DeleteFile(c *gin.Context) {
    username := c.MustGet("username").(string)
    fileID := c.Param("id")

    if fileID == "" {
        c.JSON(http.StatusBadRequest, gin.H{
            "code": 400,
            "msg":  "文件ID不能为空",
        })
        return
    }
	var req struct {
        FileName string `json:"fileName"`
    }

    // 解析请求体
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{
            "code": 400,
            "msg":  "参数错误: " + err.Error(),
        })
        return
    }

    // 删除数据库记录
    success, err := db.DeleteUserFile(username, fileID,req.FileName)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{
            "code": 500,
            "msg":  "删除失败: " + err.Error(),
        })
        return
    }

    if !success {
        c.JSON(http.StatusBadRequest, gin.H{
            "code": 400,
            "msg":  "删除失败",
        })
        return
    }

    c.JSON(http.StatusOK, gin.H{
        "code": 200,
        "msg":  "删除成功",
    })
}



// 分享文件
func CreateShare(c *gin.Context) {
	c.JSON(200, gin.H{
		"code": 200,
		"data": gin.H{
			"shareLink": "http://example.com/share/123456",
		},
	})
}

// 预览文件
func PreviewFile(c *gin.Context) {
	c.JSON(200, gin.H{
		"code": 200,
		"data": gin.H{
			"content": "文件内容...",
		},
	})
}


